package com.netrust.cmsx.entity.module.sys;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.validator.constraints.Length;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.common.collect.Lists;
import com.netrust.cmsx.core.persist.DataEntity;

@Entity
@Table(name = "sys_menu")
@JsonIgnoreProperties(value={"hibernateLazyInitializer"})
public class Menu extends DataEntity<Menu>{

	private static final long serialVersionUID = 1L;
	
	@Column(name = "parent_ids")
	private String pids; // 所有父级编号
	
	@Column(name = "name")
	private String name; 	// 名称
	
	@Column(name = "href")
	private String href; 	// 链接
	
	@Column(name = "type")
	private String type; 	// 类型  menu/permission
	
	@Column(name = "target")
	private String target; 	// 目标（ mainFrame、_blank、_self、_parent、_top）
	
	@Column(name = "icon")
	private String icon; 	// 图标
	
	@Column(name = "sort")
	private Integer sort; 	// 排序
	
	@Column(name = "is_show")
	private boolean isShow; 	// 是否在菜单中显示（true：显示；false：不显示）
	
	@Column(name = "permission")
	private String permission; // 权限标识
	
	
	@Column(name = "del_flag")
	@NotNull
	private boolean delFlag;//删除标识 （true：已删除；false：未删除）
	
	@Column(name = "remarks")
	private String remarks; // 权限标识
	
	@Transient
	private String pid; // 权限标识
	
	@ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.REMOVE}, optional=true,fetch = FetchType.LAZY)  
	@JoinColumn(name="parent_id")
	@NotFound(action=NotFoundAction.IGNORE)
	private Menu parent;	// 父级菜单
	
	@OneToMany(mappedBy="parent",cascade = { CascadeType.REFRESH, CascadeType.REMOVE }, fetch=FetchType.LAZY)
	private List<Menu> children=Lists.newArrayList();		// 根据用户ID查询角色列表
	
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
    @JoinTable(
            name="sys_role_menu",
            joinColumns=@JoinColumn(name="menu_id"),
            inverseJoinColumns=@JoinColumn(name="role_id")
    )
	private List<Role> roles=Lists.newArrayList();		// 根据用户ID查询角色列表
	
	public Menu(){
		super();
		//this.sort = 30;
		this.isShow = true;
		this.type = "menu";
		this.delFlag = false;
	}
	
	public Menu(String id){
		super(id);
	}
	
	@Length(min=1, max=2000)
	public String getPids() {
		return pids;
	}

	public void setPids(String pids) {
		this.pids = pids;
	}

	@Length(min=1, max=100)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Length(min=0, max=2000)
	public String getHref() {
		return href;
	}

	public void setHref(String href) {
		this.href = href;
	}
	
	@NotNull
	@Length(min=0, max=20)
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Length(min=0, max=20)
	public String getTarget() {
		return target;
	}

	public void setTarget(String target) {
		this.target = target;
	}
	
	@Length(min=0, max=100)
	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}
	
	@NotNull
	public Integer getSort() {
		return sort;
	}
	
	public void setSort(Integer sort) {
		this.sort = sort;
	}
	
	@NotNull
	public boolean getIsShow() {
		return isShow;
	}

	public void setIsShow(boolean isShow) {
		this.isShow = isShow;
	}

	@Length(min=0, max=200)
	public String getPermission() {
		return permission;
	}

	public void setPermission(String permission) {
		this.permission = permission;
	}
	
	@NotNull
	public boolean getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(boolean delFlag) {
		this.delFlag = delFlag;
	}
	
	public String getRemarks() {
		return remarks;
	}
	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}
	
	public String setPid(String pid) {
		return this.pid=pid;
	}
	public String getPid() {
		return pid;
	}
	

	@JsonIgnore
	@JsonBackReference
	public Menu getParent() {
		return parent;
	}

	public void setParent(Menu parent) {
		this.parent = parent;
	}
	
	@JsonIgnore
	@JsonBackReference
	public List<Menu> getChildren() {
		return children;
	}

	public void setChildren(List<Menu> children) {
		this.children = children;
	}

	@JsonIgnore
	public static void sortList(List<Menu> list, List<Menu> sourcelist, String pid, boolean cascade){
		for (int i=0; i<sourcelist.size(); i++){
			Menu e = sourcelist.get(i);
			if (e.getParent()!=null && e.getParent().getId()!=null
					&& e.getParent().getId().equals(pid)){
				list.add(e);
				if (cascade){
					// 判断是否还有子节点, 有则继续获取子节点
					for (int j=0; j<sourcelist.size(); j++){
						Menu child = sourcelist.get(j);
						if (child.getParent()!=null && child.getParent().getId()!=null
								&& child.getParent().getId().equals(e.getId())){
							sortList(list, sourcelist, e.getId(), true);
							break;
						}
					}
				}
			}
		}
	}

	@JsonIgnore
	public static String getRootId(){
		return "1";
	}

	@Override
	public String toString() {
		return name;
	}

}
